/**
 * 329. 矩阵中的最长递增路径
 * https://leetcode.cn/problems/longest-increasing-path-in-a-matrix/description/
 */

class Solution {
    int m, n;
    int[][] memoy;
    public int longestIncreasingPath(int[][] matrix) {
        m = matrix.length; n =matrix[0].length;
        memoy = new int[m][n];
        int ret = 0;
        for(int i = 0; i < m; i++) {
            for(int j = 0; j < n; j++) {
                ret = Math.max(ret, dfs(i, j, matrix));
            }
        }
        return ret;
    }
    int[] dx = {0, 0, -1, 1};
    int[] dy = {-1, 1, 0, 0};
    public int dfs(int i, int j, int[][] matrix) {
        if(memoy[i][j] != 0) {
            return memoy[i][j];
        }
        int ret = 1;
        for(int k = 0; k < 4; k++) {
            int x = dx[k] + i, y = dy[k] + j;
            if(x >= 0 && x < m && y >= 0 && y < n && matrix[x][y] > matrix[i][j]) {

                ret = Math.max(ret, dfs(x, y, matrix) + 1);
            }
        }
        memoy[i][j] = ret;
        return ret;
    }
}

/**
 *  375. 猜数字大小 II
 * https://leetcode.cn/problems/guess-number-higher-or-lower-ii/description/
 */
class Solution2 {
    int[][] memory;
    public int getMoneyAmount(int n) {
        memory = new int[n + 1][n + 1];
        return dfs(1, n);
    }

    public int dfs(int left, int right) {
        if(left >= right) return 0;
        if(memory[left][right] != 0) {
            return memory[left][right];
        }
        int ret = Integer.MAX_VALUE;
        for(int head = left; head <= right; head++) {
            int x = dfs(left, head - 1);
            int y = dfs(head + 1, right);
            ret = Math.min(Math.max(x, y) + head, ret);
        }
        memory[left][right] = ret;
        return ret;
    }
}

